﻿import {colorHelper} from "@/utils/colorHelper";
import * as echarts from 'echarts'

/**
 * 并排条形图
 */

const buildChart = function (svgSelector, data, columnFields, rowFields, options) {
  //一级维度
  var dimensionField = columnFields.find(function (d) {
    return d.slaveType === 0;
  });
  //度量
  var measureField = rowFields.find(function (d) {
    return d.slaveType === 1;
  });
  //条形图呈现方向判定
  var direction = "vertical";
  if (!dimensionField) {
    direction = "horizon";
    dimensionField = rowFields.find(function (d) {
      return d.slaveType === 0;
    });
    measureField = columnFields.find(function (d) {
      return d.slaveType === 1;
    });
  }
  if (!dimensionField || !measureField || !options.colorMark || !options.colorMark.annexField) {
    return false;
  }
  //二级维度
  var subdimensionField = options.colorMark.annexField;
  var config = options.chartConfig;
  if (!config) {
    config = {
      GlobalColor: "#4E79A7",
      MultiColors: ["#4E79A7", "#A0CBE8", "#F28E2B", "#FFBE7D", "#59A14F", "#8CD17D", "#B6992D", "#F1CE63", "#499894", "#86BCB6", "#E15759", "#FF9D9A", "#79706E", "#BAB0AC", "#D37295", "#FABFD2", "#B07AA1", "#D4A6C8", "#9D7660", "#D7B5A6"],
      scale: 0.8,
      axisStyle: {
        tickColor: "#000",
        fontColor: "#000",
        fontFamily: "Arial",
        fontSize: 12
      },
      textStyle: {
        "display": "none",
        "font-family": "Arial",
        "font-size": 12,
        "font-style": "normal",
        "font-weight": "normal",
        "fill": "#333",
        "position": "top"
      },
      xAxisLabelRotate: 0,
      showSplitLine: true,
      showAxisLine: true,
      showAxisLabel: {
        category: true,
        value: true
      },
      labelPosition: "foot",
      showLegend: true,
      xAxisName: {show: true, name: ""},//维度轴名称
      yAxisName: {show: true, name: ""},//度量轴名称-主轴
      showToolbox: true,
      legendPosition: "top",
      barBorderRadius: [0, 0, 0, 0]
    }
  }
  //图表间距
  var padding = [30, 10, 15, 10];
  if (config.chartPadding && config.chartPadding != '') {
    var arrayPadding = config.chartPadding.split(' ');
    if (arrayPadding.length >= 4) {
      padding = arrayPadding.map(function (d) {
        return parseInt(d);
      });
    }
  }
  //提取一级维度
  var categories = Enumerable.from(data).select(function (d) {
    return d[dimensionField.name];
  }).distinct().toArray();
  //按二级维度分组
  var groups = Enumerable.from(data).groupBy(function (d) {
    return d[subdimensionField.name];
  }).toArray();
  //轴文字样式
  var axis_nameTextStyle = {
    color: config.axisStyle.fontColor,
    fontSize: config.axisStyle.fontSize,
    fontFamily: config.axisStyle.fontFamily
  }
  var option_chart = {
    color: config.MultiColors,
    legend: {
      data: [],
      textStyle: axis_nameTextStyle,
      show: config.showLegend == undefined ? true : config.showLegend,
      type: 'scroll',
      pageIconColor: config.axisStyle.fontColor,
      pageTextStyle: axis_nameTextStyle
    },
    toolbox: {
      show: config.showToolbox == undefined ? true : config.showToolbox,
      //orient: 'vertical',
      //top: 'center',
      right: 5,
      feature: {
        mark: {show: true}
      },
      iconStyle: {
        borderColor: config.axisStyle.fontColor,
        textPosition: "left"
      }
    },
    tooltip: {
      axisPointer: {
        type: 'cross',
        label: {
          color: colorHelper.invert(axis_nameTextStyle.color),
          backgroundColor: axis_nameTextStyle.color
        }
      }
    },
    calculable: true,
    grid: [{
      top: (config.showLegend == undefined || config.showLegend) ? 20 + padding[0] : padding[0],
      left: padding[3],
      bottom: padding[2],
      right: padding[1],
      containLabel: true
    }],
    series: [],
    others: {
      dimensionField: dimensionField,
      measureField: measureField,
      subdimensionField: subdimensionField,
      categories: categories,
      direction: direction,
      datamarking: options.DataMarking
    }
  }
  config.legendPosition = config.legendPosition || "top";
  if (config.legendPosition == "left") {
    option_chart.legend.x = "left";
  } else if (config.legendPosition == "right") {
    option_chart.legend.x = "right";
    option_chart.toolbox.left = 20;
  }
  //数据条标签配置
  var labelOption = {
    normal: {
      show: config.textStyle["display"] !== "none",
      distance: 5,
      align: "left",
      verticalAlign: "middle",
      fontSize: config.textStyle["font-size"],
      fontFamily: config.textStyle["font-family"],
      color: config.textStyle["fill"]
    }
  };

  //轴线配置
  var axis_axisLine = {
    lineStyle: {
      color: config.axisStyle.tickColor
    },
    show: config.showAxisLine == undefined ? true : config.showAxisLine
  }
  if (direction === "vertical") {
    labelOption.normal.rotate = 90;
    if (!config.labelPosition || config.labelPosition == "foot") {
      labelOption.normal.position = "insideBottom";
    } else {
      labelOption.normal.position = "insideTop";
      labelOption.normal.align = "right";
    }
    option_chart.xAxis = [{
      type: 'category',
      axisTick: {show: false},
      data: categories,
      name: config.xAxisLabelRotate ? "" : dimensionField.name,
      nameTextStyle: axis_nameTextStyle,
      axisLine: axis_axisLine,
      axisLabel: {
        color: axis_nameTextStyle.color,
        fontSize: axis_nameTextStyle.fontSize,
        fontFamily: axis_nameTextStyle.fontFamily,
        interval: 0,
        fontWeight: "lighter",
        rotate: config.xAxisLabelRotate != undefined ? config.xAxisLabelRotate : 0,
        show: config.showAxisLabel ? config.showAxisLabel.category : true
      },
      nameLocation: "middle",
      nameGap: config.axisStyle.fontSize * 1.8,
      gridIndex: 0
    }];
    if (config.xAxisName) {
      if (config.xAxisName.show) {
        if (config.xAxisName.name) {
          option_chart.xAxis[0].name = config.xAxisName.name;
        }
      } else {
        option_chart.xAxis[0].name = "";
      }
    }
    option_chart.yAxis = [{
      type: 'value',
      name: measureField.name,
      nameTextStyle: axis_nameTextStyle,
      axisLine: axis_axisLine,
      axisTick: axis_axisLine,
      splitLine: {
        show: config.showSplitLine,
        lineStyle: {
          color: config.axisStyle.tickColor
        }
      },
      axisLabel: {
        show: config.showAxisLabel ? config.showAxisLabel.value : true,
        color: axis_nameTextStyle.color,
        fontSize: axis_nameTextStyle.fontSize,
        fontFamily: axis_nameTextStyle.fontFamily
      },
      gridIndex: 0
    }];
    if (config.yAxisName) {
      if (config.yAxisName.show) {
        if (config.yAxisName.name) {
          option_chart.yAxis[0].name = config.yAxisName.name;
        }
      } else {
        option_chart.yAxis[0].name = "";
      }
    }
  } else {
    labelOption.normal.rotate = 0;
    if (!config.labelPosition || config.labelPosition == "foot") {
      labelOption.normal.position = "insideLeft";
    } else {
      labelOption.normal.position = "insideRight";
      labelOption.normal.align = "right";
    }
    option_chart.xAxis = [{
      type: 'value',
      name: measureField.name,
      nameTextStyle: axis_nameTextStyle,
      axisLine: axis_axisLine,
      axisTick: axis_axisLine,
      splitLine: {
        show: config.showSplitLine,
        lineStyle: {
          color: config.axisStyle.tickColor
        }
      },
      axisLabel: {
        show: config.showAxisLabel ? config.showAxisLabel.value : true,
        color: axis_nameTextStyle.color,
        fontSize: axis_nameTextStyle.fontSize,
        fontFamily: axis_nameTextStyle.fontFamily
      },
      nameLocation: "middle",
      nameGap: config.axisStyle.fontSize * 1.8,
      gridIndex: 0
    }];
    if (config.yAxisName) {
      if (config.yAxisName.show) {
        if (config.yAxisName.name) {
          option_chart.xAxis[0].name = config.yAxisName.name;
        }
      } else {
        option_chart.xAxis[0].name = "";
      }
    }
    option_chart.yAxis = [{
      type: 'category',
      axisTick: {show: false},
      data: categories,
      name: config.xAxisLabelRotate ? "" : dimensionField.name,
      nameTextStyle: axis_nameTextStyle,
      axisLine: axis_axisLine,
      axisLabel: {
        color: axis_nameTextStyle.color,
        fontSize: axis_nameTextStyle.fontSize,
        fontFamily: axis_nameTextStyle.fontFamily,
        interval: 0,
        fontWeight: "lighter",
        rotate: config.xAxisLabelRotate != undefined ? config.xAxisLabelRotate : 0,
        show: config.showAxisLabel ? config.showAxisLabel.category : true
      },
      nameLocation: "start",
      inverse: true,
      gridIndex: 0
    }];
    if (config.xAxisName) {
      if (config.xAxisName.show) {
        if (config.xAxisName.name) {
          option_chart.yAxis[0].name = config.xAxisName.name;
        }
      } else {
        option_chart.yAxis[0].name = "";
      }
    }
  }
  groups.forEach(function (group) {
    var legend = group.key();
    option_chart.legend.data.push(legend);
    var source = group.getSource();
    var serie = {
      name: legend,
      type: 'bar',
      label: labelOption,
      data: [],
      itemStyle: {},
      barMaxWidth: config.scale * 100 + "%"
    }
    option_chart.series.push(serie);
    categories.forEach(function (c) {
      var find = source.find(function (d) {
        return d[dimensionField.name] === c;
      });
      if (find) {
        serie.data.push(find[measureField.name]);
      } else {
        serie.data.push(0);
      }
    });
    if (config.barBorderRadius) {
      serie.itemStyle.barBorderRadius = config.barBorderRadius;
    }
  });
  var dom_container = $(svgSelector).children('#chart')[0];
  var chartInstance = new chart(dom_container, option_chart);
  return chartInstance;
}
const chart = function (dom_container, opt) {
  var datamarkingopt = opt.others.datamarking;
  var datamarkingmapping = {}
  delete opt.others.datamarking;
  //处理数据脱敏
  if (datamarkingopt) {
    datamarkingopt.dimensions.forEach(function (dko) {
      if (dko.DataMarkingEnable) {
        datamarkingmapping[dko.name] = true;
      }
    });
  }
  var self = this;
  var myChart = echarts.init(dom_container);
  var chart_opt = {
    brush: {
      toolbox: ['rect', 'clear'],
      throttleType: "debounce",
      throttleDelay: 500
    },
    tooltip: {
      trigger: 'item',
      formatter: function (args) {
        return opt.others.dimensionField.name + ":" + args.name + "<br/>" + opt.others.subdimensionField.name + ":" + args.seriesName + "<br/>" + opt.others.measureField.name + ":" + Number(args.value).toMeasureFormart(opt.others.measureField.numberFormat);
      }
    },
    legend: {
      formatter: function (name) {
        var result = name;
        if (datamarkingopt && datamarkingmapping[opt.others.subdimensionField.name]) {
          result = result.marking();
        }
        return result;
      }
    }
  }
  var labelFormatter = function (args) {
    var seriename = args.seriesName;
    if (datamarkingopt && datamarkingmapping[opt.others.subdimensionField.name]) {
      seriename = seriename.marking();
    }
    return seriename + " " + Number(args.value).toMeasureFormart(chart_opt.others.measureField.numberFormat);
  }
  var asixLabelFormatter = function (value) {
    var result = value;
    if (datamarkingopt && datamarkingmapping[opt.others.dimensionField.name]) {
      result = result.marking();
    }
    return result;
  }
  var setOption = function (opt) {
    chart_opt = $.extend(true, chart_opt, opt);
    chart_opt.series.forEach(function (d) {
      d.label.normal.formatter = labelFormatter;
    });
    if (chart_opt.others.direction == "vertical") {
      chart_opt.xAxis[0].axisLabel.formatter = asixLabelFormatter;
    } else {
      chart_opt.yAxis[0].axisLabel.formatter = asixLabelFormatter;
    }
    myChart.setOption(chart_opt);
  }
  //响应点击事件
  myChart.on("click", function (args) {
    if (args.componentType === "series") {
      var calldata = [{
        field: chart_opt.others.dimensionField,
        value: [args.name]
      }, {
        field: chart_opt.others.subdimensionField,
        value: [args.seriesName]
      }];
      if (self.onselected) {
        self.onselected(calldata);
      }
    }
  });
  //响应框选事件
  myChart.on('brushSelected', function (args) {
    if (args.batch.length) {
      var selectedSeries = args.batch[0].selected.filter(function (d) {
        return d.dataIndex.length;
      });
      var c_idx = Array.prototype.concat.apply([], selectedSeries.map(function (d) {
        return d.dataIndex;
      }));
      c_idx = Enumerable.from(c_idx).distinct().toArray();
      var categories = [];
      chart_opt.others.categories.forEach(function (d, idx) {
        if (c_idx.includes(idx)) {
          categories.push(d);
        }
      });
      var calldata = [{
        field: chart_opt.others.dimensionField,
        value: categories
      }, {
        field: chart_opt.others.subdimensionField,
        value: selectedSeries.map(function (d) {
          return d.seriesName;
        })
      }];
      if (self.onselected) {
        self.onselected(calldata);
      }
    }
  });
  if (opt) {
    setOption(opt);
  }
  this.setOption = setOption;
  this.removeChart = function () {
      myChart.dispose();
  }
  this.resize = myChart.resize
}
export const AbreastBarChart = {
  build: buildChart
}

